#include "ollamaapi.h"
#include <QRegularExpression>

OllamaAPI::OllamaAPI(QObject *parent)
    : QObject{parent}
{
    manager = new QNetworkAccessManager(this);
    streamReply = nullptr;
    bStream = false;
    bShowThink = true;
}

int OllamaAPI::s_Id = 0;

void OllamaAPI::sendRequest(const QString &message, const QString &conversationId)
{
    curConversationId = conversationId;
    QStringList &arList = mapHistroy[conversationId];
    QUrl url("http://localhost:11434/api/chat");
    QNetworkRequest request(url);

    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QJsonArray msgs;
    for (auto his : arList) {
        QStringList info = his.split(":");
        if(info.size() > 1)
        {
            msgs.append({QJsonObject({{"role", info[0]}, {"content", info[1]}})});
        }
    }
    msgs.append({QJsonObject({{"role", "user"}, {"content", message}})});
    QJsonObject json;
    json["model"] = "deepseek-v2:16b"; // 替换为实际的模型名称
    json["messages"] = msgs;
    json["stream"] = bStream;
    arList.append("user:"+message);

    qDebug() << json;


    QJsonDocument doc(json);
    QByteArray data = doc.toJson();

    // 发送请求
    streamReply = manager->post(request, data);

    // 连接流式输出信号
    connect(streamReply, &QNetworkReply::readyRead, this, &OllamaAPI::onReadyRead);
    connect(streamReply, &QNetworkReply::finished, this, &OllamaAPI::onReplyFinished);
}

void OllamaAPI::onReadyRead()
{
    if (!streamReply) return;

    // 读取部分数据
    QByteArray chunk = streamReply->readAll();
    QString chunkText = QString::fromUtf8(chunk);

    // 解析数据块（假设 API 返回的是 JSON 格式的流式数据）
    QJsonDocument doc = QJsonDocument::fromJson(chunkText.toUtf8());
    if (!doc.isNull()) {
        QJsonObject json = doc.object();
        if(bStream && json["done"].toBool())
        {
            emit responseFinished(curConversationId);
            return;
        }
        qDebug() << json;
        QString content = json["message"].toObject()["content"].toString();
        QString role =  json["message"].toObject()["role"].toString();
        if(bStream)
        {
            if(responseText.isEmpty())
            {
                responseText = role + ":";
                emit streamResponseStarted(role, curConversationId); // 发送流式数据
            }
            if (!content.isEmpty()) {
                responseText += content;
                emit streamResponseReceived(content, curConversationId); // 发送流式数据
            }
        }
        else
        {
            if(!bShowThink)
            {
                static QRegularExpression re("<think>.*?</think>\n{2,}");
                re.setPatternOptions(QRegularExpression::DotMatchesEverythingOption); // 允许 . 匹配换行符
                content.remove(re);
                qDebug() << content;
            }
            responseText = role + ":" + content;
            emit responseReceived(content, curConversationId); // 发送流式数据
        }
    }
}

void OllamaAPI::onReplyFinished()
{
    if (streamReply->error() == QNetworkReply::NoError)
    {
        mapHistroy[curConversationId].append(responseText);
        responseText.clear();
        qDebug() << "Stream finished successfully.";
    }
    else
    {
        qDebug() << "Error:" << streamReply->errorString();
    }

    streamReply->deleteLater();
    streamReply = nullptr;
}
